![]() |
![]() |
|
JOIN-Abfragen haben einige Vorteile:
Den Vorteilen stehen auf der anderen Seite aber auch schwerwiegende Nachteile gegenüber:
ADO.NET löst die Nachteile, die eine JOIN-Abfrage hat, auf eine eigene Art und Weise. Dazu wird die JOIN-Abfrage in Einzeltabellen aufgeteilt, die miteinander in Beziehung gesetzt werden. Mit anderen Worten: Es wird ein Teil der Originaldatenbank abgebildet. Die Beziehung zwischen zwei Tabellen wird durch ein Objekt vom Typ DataRelation beschrieben.
Abbildung 26.10 Redundante Daten einer JOIN-Abfrage Obschon solchermaßen strukturierte DataSets schwer zu filtern sind, überwiegen die Vorteile. So werden weniger Daten zurückgegeben als bei einer JOIN-Abfrage. Damit wird einerseits die Netzbelastung als auch die Auslastung des lokalen Speichers so gering wie möglich gehalten. Zudem ist es viel einfacher, Daten zu aktualisieren. Löschen Sie zum Beispiel einen Datensatz aus der Detailtabelle (n-Seite), möchten Sie vermutlich nicht auch gleichzeitig den entsprechenden Datensatz der Mastertabelle löschen (1-Seite). Beide Informationen sind in einer JOIN-Abfrage jedoch in einer Datenzeile zusammengefasst. Operieren Sie mit einer DataRelation zwischen zwei DataTable-Objekten, lässt sich der Datensatz aus der Detailtabelle löschen, ohne dass zwangsläufig auch die entsprechende Datenzeile der Mastertabelle gelöscht wird. Eine »DataRelation« erzeugenMit Hilfe einer DataRelation werden zwei DataTable-Objekte über DataColumn-Objekte miteinander verknüpft. In einer author/titleauthor-Beziehung ist z.B. die Tabelle author das übergeordnete Element und die Tabelle titleauthor das untergeordnete Element der Beziehung. Dies ist vergleichbar mit einer Primärschlüssel-/Fremdschlüssel-Beziehung. Beziehungen werden zwischen einander entsprechenden Spalten in der übergeordneten und der untergeordneten Tabelle erstellt. Das heißt, dass der Datentyp für beide Spalten identisch sein muss. Aus einer längeren Liste möchte ich Ihnen einen der DataRelation-Konstruktoren vorstellen.
Dem ersten Parameter teilen Sie mit, unter welchem Namen die DataRelation angesprochen werden soll, der zweite Parameter erwartet die Referenz auf die übergeordnete Spalte der Mastertabelle (1-Seite), der dritte Parameter die Referenz auf die untergeordnete Spalte der Detailtabelle (n-Seite). Nachdem eine DataRelation erzeugt worden ist, muss sie dem DataSet bekannt gegeben werden. Dazu verwaltet das DataSet eine Auflistung des Typs DataRelationCollection, deren Referenz die Eigenschaft Relations zurück gibt. Das folgende Codefragment zeigt, wie die Beziehungen zwischen den Tabellen authors und titleauthor codiert werden.
In Beziehung stehende Daten suchenDataRelation-Objekte werden hauptsächlich dazu benutzt, um Daten, die in verschiedenen DataTable-Objekten enthalten sind, zu suchen. Zu diesem Zweck stellt eine DataRow drei Methoden zur Verfügung, die auf einer DataRelation basieren:
GetChildRows sucht, ausgehend von einer Datenzeile in der Mastertabelle, alle zugehörigen untergeordneten Datenzeilen in der Detailtabelle. Dazu übergeben Sie der Methode die DataRelation, die beide Tabellen miteinander verknüpft, und erhalten als Ergebnis ein DataRow-Array.
Ausgehend von der untergeordneten Zeile einer Detailtabelle ruft GetParentRow die zugehörige übergeordnete Datenzeile aus einer Mastertabelle ab. Auch dieser Methode müssen Sie die DataRelation zwischen den beiden Tabellen angeben, der Rückgabewert ist eine einzige Datenzeile.
Sollte zwischen zwei Tabellen eine n:m-Beziehung bestehen, können Sie die GetParentRows-Methode einsetzen.
Ich möchte Ihnen nun in einem Beispielprogramm die Benutzung der Methoden zeigen. Es sollen zu jedem Autor die von ihm veröffentlichten Titel ausgegeben werden. Ausgangspunkt dazu sind die drei Tabellen authors, titleauthor und titles, wie in Abbildung 26.9 zu sehen ist.
In einer äußeren foreach-Schleife werden alle Datenzeilen der Tabelle der Autoren nacheinander durchlaufen. Auf jede Datenzeile wird GetChildRows aufgerufen, die alle Datensätze in titleauthor liefert. Ausgehend von jedem einzelnen Resultat wird über GetParentRow der Titel ermittelt. Die Ausgabe des Beispiels sehen Sie in Abbildung 26.11.
Abbildung 26.11 Ausgabe des Beispielprogramms »DataRelationDemo« 26.6.3 Änderungen an einer »DataTable« vornehmen
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ds.Tables[0].Rows[3]["au_lname"] = "Fischer"; |
Die Änderung wird sofort in die angegebene Spalte der entsprechenden Datenzeile geschrieben.
Die zweite Alternative puffert die Änderung. Dazu wird vor Beginn der Änderung die Methode BeginEdit auf die DataRow aufgerufen und nach Beendigung EndEdit. Sie können die eingeleitete Aktualisierung auch zurücknehmen und anstelle von EndEdit die Methode CancelEdit aufrufen. Die Zeile wird dann in den Zustand zurückversetzt, den sie vor BeginEdit hatte.
| DataRow row = ds.Tables[0].Rows[3]; |
| row.BeginEdit(); |
| row["au_lname"] = "Fischer"; |
| row.EndEdit(); |
| // alternativ: row.Canceledit() |
Die Pufferung der Änderung ist nicht der einzige Unterschied zwischen den beiden Aktualisierungsmöglichkeiten. Die DataTable verfügt über mehrere Ereignisse, die nur im Zusammenhang mit BeginEdit und EndEdit ausgelöst werden. Es handelt sich hierbei um
| RowChanging |
| RowChanged |
| ColumnChanging |
| ColumnChanged |
Diese Ereignisse spielen eine Rolle, wenn Änderungen an einer Datenzeile oder Spalte überprüft werden müssen. Wenn wir uns später dem Zurückschreiben der Änderungen in die Originaldatenbank zuwenden, werden wir noch einmal diese Ereignisse berücksichtigen.
Das Löschen einer Datenzeile ist sehr einfach: Sie rufen die Methode Delete der DataRow auf, die gelöscht werden soll.
| row.Delete(); |
Es ist falsch anzunehmen, dass die betreffende Datenzeile nun aus der DataTable entfernt wird. Sie ist immer noch vorhanden, allerdings kennzeichnet ADO.NET sie als gelöscht. Hintergrund der Markierung ist, dass das Löschen zunächst nur das aktuelle DataSet betrifft und zu einem späteren Zeitpunkt der Originaldatenbank mitgeteilt werden muss. Es wäre daher auch grundlegend falsch, eine Datenzeile mit Remove oder RemoveAt aus der DataRowCollection der Tabelle zu entfernen, denn dann findet der Aktualisierungsprozess die Datenzeile nicht mehr.
Eine Datenzeile zu einer DataTable hinzuzufügen, ist auch nicht schwierig. Rufen Sie dazu die Methode NewRow auf das DataTable-Objekt auf. ADO.NET erstellt daraufhin eine neue Datenzeile mit dem Schema der Tabelle. Wenn im Schema keine Standardwerte vorgegeben werden, sind die Inhalte der Spalten auf NULL gesetzt. Haben Sie alle Einträge in der neuen Zeile vorgenommen, müssen Sie die neue Zeile auch noch der DataRowCollection anhängen, denn das ist zu diesem Zeitpunkt noch nicht geschehen.
| DataTable tbl = ds.Tables[0]; |
| DataRow row = tbl.NewRow(); |
| row["au_id"] = "123–56–6789"; |
| row["au_lname"] = "Meier"; |
| row["au_fname"] = "Franz"; |
| // ... |
| tbl.Rows.Add(row); |
Ein DataSet ist im lokalen Cache des Benutzers abgelegt. Während des Löschen, Änderns und Hinzufügens von Datenzeilen besteht zu der Originaldatenbank keine Verbindung. Wenn der Benutzer später die geänderten Daten an die Datenbank übermitteln möchte, muss sich das DataSet daran erinnern können, welche Zeilen von einer Änderung betroffen sind.
ADO.NET speichert diese Informationen in der Eigenschaft RowState der betreffenden Datenzeile. Die Eigenschaft wird durch einen Wert der Enumeration DataRowState beschrieben.
| public DataRowState RowState {get;} |
DataRowState beschreibt fünf Konstanten, die Sie der folgenden Tabelle entnehmen können.
| Member | Beschreibung |
| Added | Die Zeile wurde einer DataRowCollection hinzugefügt. |
| Deleted | Die Zeile wurde mit der Delete-Methode der DataRow gelöscht. |
| Detached | Die Zeile wurde erstellt, ist jedoch nicht Teil einer DataRowCollection. Eine DataRow befindet sich in diesem Zustand, wenn sie unmittelbar nach ihrer Erstellung noch keiner Auflistung hinzugefügt wurde oder wenn sie aus einer Auflistung entfernt wurde. |
| Modified | Die Zeile wurde geändert. |
| Unchanged | Die Zeile wurde nicht geändert. |
Nicht nur, dass jede Datenzeile dahingehend gekennzeichnet ist, welche Änderung ihr widerfahren ist (oder auch nicht), Sie können sogar den ursprünglichen Spalteninhalt auswerten. Für diesen Zweck ist der Indexer einer DataRow überladen.
| public object this[string columnName, DataRowVersion version] {get;} |
An Stelle des Bezeichners der Spalte im ersten Parameter können Sie hier auch den Ordinalwert (= Index) oder die Referenz auf eine DataColumn angeben.
DataRowVersion ist eine Aufzählung, mit der die gewünschte Version der betreffenden Spalte in der Datenzeile angegeben werden kann.
| Member | Beschreibung |
| Current | Die Zeile enthält aktuelle Werte. |
| Default | Die Zeile enthält einen vorgeschlagenen Wert. |
| Original | Die Standardversion der Zeile, dem aktuellen DataRowState entsprechend. |
| Proposed | Die Zeile enthält ihre ursprünglichen Werte. |
Rufen Sie mit
| row["contract"] |
den Inhalt einer Spalte ab, wird immer DataRowVersion.Current ausgewertet. Das ist wichtig zu wissen, denn sollten Sie die DataRowCollection in einer Schleife durchlaufen, innerhalb der zum Beispiel auf Spalten aller geänderten Zeilen zugegriffen wird, dürfen Sie von einer gelöschten Zeile nicht DataRowVersion.Current abrufen. Sie können aber sehr wohl DataRowVersion.Original auswerten, weil eine als gelöscht markierte Datenzeile nicht aus der DataRowCollection entfernt wird.
Das nächste Beispiel zeigt Ihnen die prinzipielle Vorgehensweise. Nachdem das DataSet aus der Autorentabelle mit Daten gefüllt worden ist, wird zuerst ein weiterer Datensatz hinzugefügt. Anschließend wird die Liste der Datenzeilen durchlaufen und geprüft, ob der aktuell sich im Zugriff befindliche Autor Herr White ist. Wenn ja, wird der Zuname geändert. Sollte es sich um den Autor Ringer handeln, wird der Datensatz gelöscht.
Am Ende werden noch alle geänderten Datenzeilen gesucht und jeweils der Name des Autors ausgegeben.
| // -------------------------------------------------------------- |
| // Beispiel: ...\Kapitel 26\DataRowVersionDemo |
| // -------------------------------------------------------------- |
| static void Main(string[] args) { |
| // Connection aufbauen |
| string strSQL = "SELECT au_id, au_lname, au_fname, contract FROM authors"; |
| string strCon = "..."; |
| SqlConnection con = new SqlConnection(strCon); |
| // DataAdapter definieren |
| SqlDataAdapter da = new SqlDataAdapter(strSQL, con); |
| DataSet ds = new DataSet(); |
| da.Fill(ds); |
| // DataRow hinzufügen |
| DataTable tbl = ds.Tables[0]; |
| DataRow row = tbl.NewRow(); |
| row["au_id"] = "123–56–6789"; |
| row["au_lname"] = "Meier"; |
| row["au_fname"] = "Franz"; |
| row["contract"] = 0; |
| tbl.Rows.Add(row); |
| // DataRow editieren |
| foreach (DataRow tempRow in tbl.Rows) { |
| if (tempRow["au_lname"].ToString() == "White") |
| tempRow["au_lname"] = "Yellowman"; |
| else if (tempRow["au_lname"].ToString() == "Ringer") |
| tempRow.Delete(); |
| } |
| // Ausgabe der geänderten Datenzeilen |
| foreach (DataRow editRow in tbl.Rows) |
| if (editRow.RowState == DataRowState.Added) |
| Console.WriteLine("Autor {0} – Added",editRow["au_lname"]); |
| else if(editRow.RowState == DataRowState.Modified) |
| Console.WriteLine("Autor {0} – Modified", editRow["au_lname"]); |
| else if (editRow.RowState == DataRowState.Deleted) |
| Console.WriteLine("Autor {0} – Deleted", |
| editRow["au_lname", DataRowVersion.Original]); |
| Console.ReadLine(); |
| } |
Im Abschnitt 26.4.4 haben Sie gelernt, wie Sie mit Hilfe der vom Visual Studio 2005 bereitgestellten Controls einen DataAdapter konfigurieren können. An dieser Stelle setzen wir an und wollen jetzt die Schritte so weit vollziehen, dass die Dateninformationen auch in dafür geeigneten Steuerelementen angezeigt werden.
Die Ausgangssituation sei die: Sie haben ein SqlDataAdapter-Steuerelement in eine WinForm gezogen, die Verbindung zur Datenbank pubs und deren Tabelle authors konfiguriert. Markieren Sie nun im Komponentenfach des Designers das DataAdapter-Steuerelement. Im unteren Bereich des Eigenschaftsfenster wird Ihnen dann der Link DataSet generieren ... angezeigt, auf den Sie klicken. Es öffnet sich ein Dialog (siehe Abbildung 26.12), den Sie ohne weitere Änderungen mit OK bestätigen können.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.12 Dialog zum Generieren eines DataSets
Sie haben jetzt ein so genanntes typisiertes DataSet erzeugt, das Ihnen beim Programmieren einer Datenbankanwendung durchaus sehr nützlich sein kann. Typisierten DataSets liegt eine Klassendefinition zugrunde, die Sie in unserem Beispiel in der Datei DataSet1.Designer.cs wiederfinden. Die Komponente dataSet11, die Sie im Komponentenfach sehen, ist die Instanz der Klasse des typisierten DataSets. Wir werden uns in diesem Buch nicht weiter mit typisierten DataSets beschäftigen, weil das den Rahmen sprengen würde.
Der Inhalt der Tabelle authors soll in einem Tabellensteuerelement angezeigt werden. Hier bietet uns das Visual Studio 2005 das Control DataGridView an, das wir in die Form ziehen. Es öffnet sich sofort eine SmartTag-Unterstützung, um das Steuerelement mit einer geeigneten Datenquelle zu verbinden, die in unserem Fall das Objekt dataSet11 ist. Öffnen Sie dazu das mit Datenquelle auswählen beschriftete Kombinationslistenfeld und navigieren zu dataSet11, wie in Abbildung 26.13 gezeigt. Sie können die Datenquelle aber auch im Eigenschaftsfenster des DataGridView einstellen, indem Sie die Eigenschaft DataSource passend einstellen.
Ein DataSet kann bekanntlich grundsätzlich mehrere Tabellen beherbergen. Das gilt auch für unser Objekt dataSet11. Da ein DataGridView aber nur den Inhalt einer DataTable anzeigen kann, müssen Sie diese noch ausdrücklich dem Steuerelement bekannt geben. Das machen Sie, indem Sie die Tabelle in der Eigenschaft DataMember angeben.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.13 Auswahl der Datenquelle
Das Ergebnis ist schon sehr positiv, denn bereits im Designer können Sie innerhalb des Tabellensteuerelements die Spaltenbezeichner der ausgewählten Tabelle erkennen. Sollten Ihnen die Bezeichner au_id, au_lname usw. nicht gefallen, das Visual Studio bietet Ihnen selbstverständlich auch die Möglichkeit an, mittels Assistenten die Spaltenbezeichner nach eigenen Wünschen einzustellen. Markieren Sie einfach das Tabellensteuerelement und öffnen über dessen Eigenschaft Columns einen Dialog, der es ermöglicht, die Vorgabe der Spaltenbezeichner für jede Spalte individuell festzulegen.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.14 Ändern der Spaltenüberschriften
Sie werden spätestens an dieser Stelle probieren, wie sich die Tabelle zur Laufzeit der Anwendung präsentiert. Das Ergebnis ist aber ernüchternd: Die Tabelle bleibt leer. Denn eine Kleinigkeit müssen wir doch noch programmieren: den Aufruf der Fill-Methode des DataSet-Objekts. Die erforderliche Anweisung kann im Konstruktor der Form codiert werden, aber erst nach dem Aufruf von InitializeComponent.
| public Form1() { |
| InitializeComponent(); |
| sqlDataAdapter1.Fill(dataSet11); |
| } |
Zur Laufzeit könnte sich die WinForm wie in Abbildung 26.15 darstellen.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.15 Gefülltes DataGridView-Steuerelement
Per Voreinstellung lassen sich die angezeigten Daten manipulieren. Sie können also Datenzeilen hinzufügen oder löschen sowie Daten ändern. In der SmartTag-Unterstützung lassen sich diese Vorgaben beliebig einstellen. Sie können das Aktualisierungsverhalten jedoch auch im Eigenschaftsfenster mit den Eigenschaften
| AllowUserToAddRows |
| AllowUserToDeleteRows |
| ReadOnly |
beeinflussen. Änderungen werden nicht sofort an die Originaldatenbank übermittelt. Hier gilt dasselbe wie schon beim Füllen des DataSets: Sie müssen die Methode Update des DataAdapters manuell codieren. Mehr dazu im Abschnitt 26.7.
Neben dem DataGridView ist auch eine Vielzahl weiterer Steuerelemente datenbindungsfähig. Sie unterscheiden sich voneinander durch die Eigenschaften, die Dateninformationen aus einer Datenquelle anzeigen können. Ihnen ist aber eins gemeinsam: Sie werden an eine bestimmte Spalte einer Tabelle gebunden.
Die Einstellungen nehmen Sie im Eigenschaftsfenster vor. Öffnen Sie in der linken Spalte den Eintrag (DataBindings), werden alle Eigenschaften angeboten, die sich grundsätzlich dazu eignen, Daten aus einer Datenquelle wiederzugeben. Bei der sehr häufig verwendeten TextBox handelt es sich beispielsweise um die beiden Eigenschaften Tag und Text. Ein Klick auf die Schaltfläche in der Wertespalte öffnet ein Hilfsfenster, in dem Sie die von Ihnen gewünschte Spalte der Datenquelle markieren. In Abbildung 26.16 handelt es sich um die Spalte au_lname der Tabelle authors des DataSets dataSet11.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.16 Auswahl der gebundenen Spalte
Die Navigation durch die Datenzeilen einer Tabelle in einem Tabellensteuerelement bedarf keiner besonderen Aufmerksamkeit. Etwas anders verhält es sich, wenn nur der Spaltenwert der aktuellen Datenzeile einer DataTable in den Steuerelementen angezeigt werden kann. Wir benötigen in der Form dann Navigationsschaltflächen, um eine beliebige Datenzeile anzeigen zu können. In der Regel werden dazu Schaltflächen angeboten, die das Navigieren zum ersten, zum letzten, zum vorherigen und zum nächsten Datensatz erlauben.
Um durch Datenzeilen zu navigieren, verwenden datengebundene Steuerelemente eine Instanz der Klasse CurrencyManager. Diese Instanz wird einer Tabelle oder einem DataSet zugeordnet. Das CurrencyManager-Objekt veröffentlicht die Eigenschaft Position, die dazu verwendet wird sicherzustellen, dass die einzelnen Steuerelemente Daten im gleichen Datensatz lesen und schreiben.
Über die Eigenschaft BindingContext der Form wird die Verbindung zwischen den Steuerelementen in der Form und dem CurrencyManager hergestellt, z.B.:
CurrencyManager cm = (CurrencyManager)BindingContext[dataSet11, "authors"];
Je nachdem, auf welche Navigationsschaltfläche der Anwender klickt, muss jetzt nur noch die Position-Eigenschaft entsprechend angepasst werden, beispielsweise im Click-Ereignis der Schaltfläche, mit der zur nächsten Datenzeile gesprungen werden soll mit:
cm.Position++;
Alle anderen datengebundenen Steuerelemente passen ihre Ausgabe an den Inhalt der nun aktuellen Datenzeile an.
Im folgenden Beispielprogramm ist die in Abbildung 26.17 gezeigte Form vollständig codiert, so dass mit den vier Schaltflächen zwischen den Datenzeilen einer DataTable, welche die Tabelle authors enthält, navigiert werden kann. Zwischen den Schaltflächen informiert ein Label-Steuerelement den Anwender darüber, welche Datenzeile aktuell angezeigt wird.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.17 Ausgabe des Beispielprogramms »DatengebundeneControls«
| // ------------------------------------------------------ |
| // Beispiel: ...\Kapitel 26\DatengebundeneControls |
| // ------------------------------------------------------ |
| public partial class Form1 : Form { |
| CurrencyManager cm; |
| public Form1() { |
| InitializeComponent(); |
| sqlDataAdapter1.Fill(dataSet11); |
| cm = (CurrencyManager)BindingContext[dataSet11, "authors"]; |
| cm.PositionChanged += new EventHandler(cm_PositionChanged); |
| DisplayPosition(); |
| } |
| private void DisplayPosition() { |
| lblPosition.Text = cm.Position + 1 + " von " + cm.Count; |
| } |
| private void cm_PositionChanged(object sender, EventArgs e) { |
| DisplayPosition(); |
| } |
| private void btnFirst_Click(object sender, EventArgs e) { |
| cm.Position = 0; |
| } |
| private void btnPrevious_Click(object sender, EventArgs e) { |
| cm.Position--; |
| } |
| private void btnNext_Click(object sender, EventArgs e) { |
| cm.Position++; |
| } |
| private void btnLast_Click(object sender, EventArgs e) { |
| cm.Position = cm.Count – 1; |
| } |
| } |
Eine weitere, etwas einfachere Möglichkeit der Datenbindung bietet die vom Visual Studio 2005 angebotene Komponente BindingSource. Diese unterstützt die Bindung von Steuerelementen in einer Form und kann als Bindeglied zwischen einer Datenquelle und den Steuerelementen angesehen werden. BindingSource ersetzt den im letzten Abschnitt beschriebenen CurrencyManager.
Nachdem Sie aus der Toolbox eine BindingSource-Komponente auf die Form gezogen haben, müssen Sie zwei Eigenschaften einstellen, um dem Objekt eindeutig die Datenquelle bekannt zu geben:
| DataSource |
| DataMember |
Mehrere Dialoge führen Sie automatisch zum Ziel. Nachdem Sie DataSource im Eigenschaftsfenster markiert haben, klicken Sie auf den Link Projektdatenquelle hinzufügen im Hilfsfenster der Wertespalte. Im ersten Dialogfenster des Assistenten zum Konfigurieren von Datenquellen (Abbildung 26.18) können Sie zwischen einer Datenbank, einem Webdienst und einem datenführenden Objekt auswählen. Datenbank ist dabei schon vorselektiert.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.18 Auswählen eines Datenquellentyps
Über Weiter gelangen Sie zum zweiten Dialog, in dem Sie eine bestehende Datenbankverbindung aussuchen oder eine neue erstellen können. Legen Sie über Neue Verbindung... eine neue an, wird der in Abbildung 26.1 gezeigte Dialog geöffnet, in dem Sie den Datenbankserver, die Authentifizierung und die Datenbank angeben müssen.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.19 Datenverbindung bekannt geben
Auf Basis der nun bekannten Verbindungsinformationen legen Sie im letzten Dialog des Assistenten fest, welche Datenbankobjekte das DataSet enthalten soll. Zur Auswahl stehen Tabellen, Ansichten, gespeicherte Prozeduren und Funktionen. Öffnen Sie den entsprechenden Knoten, beispielsweise den der Tabellen, sehen Sie alle Tabellen aufgelistet, die in der Datenbank definiert sind. Sie können nun auch die Spalten bestimmen, die vom DataTable-Objekt beschrieben werden sollen. Die Angabe mehrerer, auch unterschiedlicher Datenbankobjekte ist durchaus möglich.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.20 Auswahl der Datenbankobjekte
Das Fertigstellen des Assistenten bewirkt, dass der Form ein (typisiertes) DataSet hinzugefügt wird. Damit ist die Grundlage geschaffen, Sie müssen nur noch der Eigenschaft DataMember des BindingSource-Objekts die Tabelle angeben. Damit wird gleichzeitig die Instanz eines TableAdapters erzeugt. Ein TableAdapter ist ähnlich einem DataAdapter, nur bezogen auf eine DataTable. Das TableAdapter-Objekt wird namentlich eindeutig gekennzeichnet. Beschreibt es die Tabelle authors, lautet der Bezeichner authorsTableAdapter. Sie finden das Objekt im Komponentenfach.
Die Steuerelemente, die Dateninformationen anzeigen sollen, müssen jetzt mit dem BindingSource-Objekt verknüpft werden. Das geschieht ebenfalls über den Eintrag (DataBindings) im Eigenschaftsfenster des entsprechenden Elements. Allerdings wird Ihnen nun auch das BindingSource-Objekt zur Auswahl mit angeboten. Handelt es sich um ein Tabellensteuerelement, wählen Sie aus der zur Eigenschaft DataSource angebotenen Liste das Bindungsobjekt aus.
Eine weitere Neuerung des Visual Studios 2005 ist das Steuerelement BindingNavigator. Dabei handelt es sich um eine speziell ausgebildete Toolbar, in der nicht nur die obligatorischen Navigationsschaltflächen, sondern darüber hinaus auch eine Schaltfläche zum Hinzufügen einer Datenzeile und zum Löschen der momentan aktuellen angeboten werden. Datenanzeigende Steuerelemente, welche die gleiche Bindungsquelle benutzen, werden ihr Verhalten hinsichtlich Navigation und Editierung den Aktionen im BindingNavigator anpassen.
Ein BindingNavigator-Steuerelement kann in einen ToolStripContainer eingebettet werden. Per Vorgabe wird das Control oben ausgerichtet. Sie haben, wie bei einem ToolStrip, ferner die Möglichkeit, das Steuerelement um zusätzliche Elemente zu ergänzen. Die bereits enthaltenen können Sie mit entsprechende Eigenschaften abschalten oder sogar ganz löschen.
Damit das Control auch wie beabsichtigt seine Aufgabe erledigt, muss ihm die Datenquelle genannt werden. Geben Sie daher der Eigenschaft BindingSource das gewünschte BindingSource-Objekt an. Jetzt ist BindingNavigator so weit vorbereitet, als Bindeglied zwischen Datenquelle und den datengebundenen Steuerelementen seine Arbeit zu verrichten.

Hier klicken, um das Bild zu vergrößern
Abbildung 26.21 Das Steuerelement »BindingNavigator«
Auf der Buch-CD finden Sie das zu Abbildung 26.21 gehörige Beispielprogramm BindingNavigatorDemo.
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.